const { User, Dept, Attachment } = require("../../models");
const { Op } = require("sequelize");
const { success, failure } = require("../../utils/responses");
const { paging } = require("../../utils/utils");
const { NotFoundError } = require("../../utils/errors");
const fs = require("fs");
const {
  deleteAttachmentByBusinessId,
  deleteFileAttachmentByBusinessId,
  saveAttachment,
} = require("../../services/upload/attachmentService");

/**
 * 分页数据列表
 * @param req
 * @param res
 */
exports.list = async (req, res) => {
  // 查询所有数据
  try {
    // 获取分页参数
    const { query, currentPage, pageSize, offset } = paging(req);
    // 排序+分页
    const condition = {
      order: [["id", "DESC"]],
      limit: pageSize,
      offset: offset,
      include: [
        {
          model: Dept,
          as: "dept",
          attributes: ["id", "name"],
        },
      ],
    };
    const { username, phone, status, deptId } = query;
    if (phone) {
      condition.where = {
        phone: {
          [Op.like]: `%${phone}%`,
        },
      };
    }
    if (username) {
      condition.where = {
        username: {
          [Op.like]: `%${username}%`,
        },
      };
    }
    if (status) {
      condition.where = {
        status: {
          [Op.like]: `%${status}%`,
        },
      };
    }
    if (deptId) {
      condition.where = {
        parentId: {
          [Op.eq]: deptId,
        },
      };
    }
    // 分页查询
    const { count, rows } = await User.findAndCountAll(condition);
    // 返回
    success(res, "查询成功", {
      lists: rows,
      pagination: {
        total: count,
        currentPage,
        pageSize,
      },
    });
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 新增
 * @param req
 * @param res
 */
exports.add = async (req, res) => {
  try {
    const body = filterBody(req);
    body.password = req.body.password;
    const data = await User.create(body);
    success(res, "创建成功", data, 201);
  } catch (error) {
    console.log(error);
    failure(res, error);
  }
};

/**
 * 更新
 * @param req
 * @param res
 */
exports.update = async (req, res) => {
  try {
    const data = await getById(req);
    const body = filterBody(req);
    await data.update(body);
    success(res, "更新成功", data);
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 更新密码
 * @param req
 * @param res
 */
exports.updatePassword = async (req, res) => {
  try {
    const data = await getById(req);
    await data.update({ password: String(req.body.password) });
    success(res, "更新成功", data);
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 保存权限信息
 * @param req
 * @param res
 */
exports.addRoleId = async (req, res) => {
  try {
    const data = await getById(req);
    const roles = req.body.roles;
    const rolesId = req.body.rolesId;
    await data.update({
      roles: JSON.stringify(roles),
      rolesId: JSON.stringify(rolesId),
    });
    success(res, "更新成功", data);
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 选中的角色列表
 * @param req
 * @param res
 */
exports.getRoleUserIds = async (req, res) => {
  try {
    const userId = req.query.userId;
    const data = await User.findByPk(userId);
    if (!data) {
      throw new NotFoundError(`ID: ${id} not found`);
    }
    const rolesId = data.rolesId || "[]";
    success(res, "更新成功", JSON.parse(rolesId));
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 删除
 * @param req
 * @param res
 */
exports.del = async (req, res) => {
  try {
    const data = await getById(req);

    // 删除用户的头像附件及文件
    await deleteFileAttachmentByBusinessId(data.id);

    await data.destroy();
    success(res, "删除成功");
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 详情
 * @param req
 * @param res
 */
exports.details = async (req, res) => {
  try {
    const data = await getById(req);
    success(res, "查询成功", data);
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 更新用户头像地址
 * @param req
 * @param res
 */
exports.uploadAvatar = async (req, res) => {
  try {
    const data = await getById(req);
    const file = req.file;
    const filePath = file.destination + file.originalname;
    // 删除附件信息
    await deleteAttachmentByBusinessId(data.id);
    // 保存附件信息
    await saveAttachment({
      businessId: data.id,
      fileSize: req.file.size,
      fileType: req.file.mimetype,
      filename: req.file.originalname,
      filePath,
      remark: req.body.remark,
      tableName: "users",
    });
    // 更新头像地址
    const user = await data.update({ avatar: filePath });
    success(res, "上传成功", user);
  } catch (error) {
    failure(res, error);
  }
};

/**
 * 获取当前
 * @param req
 */
async function getById(req) {
  const id = req.body.id || req.params.id || req.query.id; //获取ID
  const data = await User.findByPk(id);
  if (!data) {
    throw new NotFoundError(`ID: ${id} not found`);
  }
  return data;
}

/**
 * 公共方法过滤白名单
 * @param req
 * @returns {{password, role: (number|string|*), introduce: ({type: *}|*), sex: (number|*), nickname: (string|*), company: ({type: *}|*), avatar: ({type: *, validate: {isUrl: {msg: string}}}|*), email: (string|*), username}}
 */
function filterBody(req) {
  return {
    email: req.body.email,
    username: req.body.username,
    nickname: req.body.nickname,
    sex: req.body.sex,
    company: req.body.company,
    introduce: req.body.introduce,
    phone: req.body.phone,
    status: req.body.status,
    deptId: req.body.deptId,
    deptName: req.body.deptName,
    remark: req.body.remark,
    parentId: req.body.parentId,
  };
}
